package com.grailslm

import org.dom4j.Element
import org.dom4j.Namespace
import org.dom4j.VisitorSupport
import org.dom4j.io.SAXReader
import org.dom4j.tree.DefaultElement
import javax.xml.parsers.SAXParserFactory
import javax.xml.transform.stream.StreamSource
import javax.xml.validation.SchemaFactory

/**
 * Xpath && GPath
 */
class Example
{

    /**
     *  处理默认命名空间问题
     */
    class XPathVisitor extends VisitorSupport {
        Namespace namespace = null //默认命名空间

        XPathVisitor() {
            this.namespace = Namespace.NO_NAMESPACE
        }

        XPathVisitor(Namespace namespace) {
            this.namespace = namespace
        }

        void visit(Element node) {
            if (node instanceof DefaultElement && node.getNamespacePrefix().isEmpty()) {
                ((DefaultElement) node).setNamespace(this.namespace) //设置“默认命名空间”
            }
        }
    }

    /**
     * groovy + GPath
     */
    static def t1(File file) {
        def root = new XmlParser().parse(file)
        root.children().each {Node child->
            println child.name()
        }

        println "---"
        println root.cd
        println root.table
    }

    /**
     * dom4j + XPath（忽略“默认命名空间”）
     */
    def t2(File file) {
        SAXReader reader = new SAXReader()
        def document = reader.read(file)
        def root = document.getRootElement()
        root.elements().each {Element child->
            println "{${child.getNamespaceURI()}}" + child.getName()
        }

        println "---"
        document.accept(new XPathVisitor())
        println document.selectNodes("/catalog/cd")
        println document.selectNodes("/catalog/table")
    }

    /**
     * dom4j + XPath（处理“默认命名空间”）
     */
    static def t3(File file) {
        SAXReader reader = new SAXReader()
        def document = reader.read(file)

        def xpath = document.createXPath("//ns:cd") //ns:cd，html4:table，w3school:table
        xpath.setNamespaceURIs(["ns":"http://lvchanglong.com", "html4":"http://www.w3.org/TR/html4/", "w3school":"http://www.w3school.com.cn/furniture"])
        println xpath.selectNodes(document)
    }

    /**
     * dom4j + XPath（xml & xsd 融合，解决xsd默认值在xml中无法读取问题）
     */
    def t4(File file, ArrayList<StreamSource> sources) {
        SAXParserFactory parserFactory = SAXParserFactory.newInstance()
        parserFactory.setSchema(SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema").newSchema(sources))
        SAXReader reader = new SAXReader(parserFactory.newSAXParser().getXMLReader())
        reader.setValidation(false) //是否校验

        def document = reader.read(file)

        def bkNamespace = document.getRootElement().getNamespace() //备份默认命名空间

        println document.asXML()
        document.accept(new XPathVisitor())
        println document.asXML()

        println "-------------------------------"
        println document.selectNodes("/书架/书/作者[@字='深思君']")
        println "-------------------------------"

        document.accept(new XPathVisitor(bkNamespace)) //还原默认命名空间
        println document.asXML()
    }

    static void main(def args) {
        def file = new File("C:\\workspace\\exmaples\\XPath-demo\\src\\main\\groovy\\com\\grailslm\\demo.xml")

//        new Example().t1(file)
//        println "----------------------------------------------"
//        new Example().t2(file)
//        println "----------------------------------------------"
//        new Example().t3(file)
//        println "----------------------------------------------"
        new Example().t4(new File("C:\\workspace\\exmaples\\XPath-demo\\src\\main\\groovy\\com\\grailslm\\xsd.xml"), [new StreamSource("C:\\workspace\\exmaples\\XPath-demo\\src\\main\\groovy\\com\\grailslm\\xsd-demo.xsd")])
    }

}
